home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Core / Includes / UStream.h < prev    next >
Encoding:
Text File  |  1996-04-03  |  17.1 KB  |  523 lines  |  [TEXT/MPS ]

  1. // UStream.h
  2. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  3. // Originally written by Larry S. Rosenstein. Used by permission
  4.  
  5.  
  6. #ifndef __USTREAM__
  7. #define __USTREAM__
  8.  
  9. // MacApp
  10.  
  11. #ifndef __GEOMETRY__
  12. #include "Geometry.h"
  13. #endif
  14.  
  15. #ifndef __TOOLBOX__
  16. #include "Toolbox.h"
  17. #endif
  18.  
  19. #ifndef __UGEOMETRY__
  20. #include "UGeometry.h"
  21. #endif
  22.  
  23. #ifndef __UOBJECT__
  24. #include "UObject.h"
  25. #endif
  26.  
  27. // Toolbox
  28.  
  29.  
  30. //----------------------------------------------------------------------------------------
  31. // Forward class declarations. 
  32. //----------------------------------------------------------------------------------------
  33.  
  34. //    class TFile;
  35. class TList;
  36.  
  37. //----------------------------------------------------------------------------------------
  38. // This unit implements a rudimentary stream abstract type, and subclasses that do I/ O
  39. // to files and handles. This can be used to implement document I/ O and clipboard I/ O
  40. // with the same code. Streams can write out and read back objects, using the features
  41. // in UObject to get an object's class ID and name. The format of an object in the stream
  42. // is as follows:
  43. //
  44. //        2 bytes        delimiter
  45. //        if (delimiter == kNullObject)            no object, so...
  46. //            that's all folks!
  47. //        else if (delimiter == kIndex)            object has been seen
  48. //            4 bytes        index into TContext
  49. //        else
  50. //        {
  51. //            if (delimiter == kClassID)
  52. //                4 bytes        class ID (at the time it was written) 4 bytes for model far code
  53. //            else if (delimiter == kSignature)
  54. //                4 bytes        signature
  55. //            4 bytes        size of object in stream, excluding class ID
  56. //            1 byte        size of class name
  57. //            n bytes        class name
  58. //            m bytes        data specific to object
  59. //        }
  60. //
  61. // The class ID in the stream might not match the class ID of the same class in the
  62. // current application. (It depends on how the class IDs were assigned.) The stream code
  63. // uses the class name to identify the actual class. It is not necessary, however, to
  64. // write out the class name for every class. The stream will associate the classID in
  65. // the stream with the correct class ID for the application. The first object of a given
  66. // class has its name written into the stream, along with its classID. When read back,
  67. // the name is used to find the class ID in the current application, which is associated
  68. // with the class ID in the stream.  Subsequent objects of that class can be written with
  69. // an empty class name, and the table of class IDs will be consulted to find out the
  70. // proper class ID.
  71. //
  72. // TStream handles structures in which objects are referenced more than once using
  73. // TContext which maintains a table of all the objects written out. The first time an
  74. // object is written it is added to the table.If the same object is written again, only
  75. // its table index is written. A similar process is used to read the object back.
  76. //
  77. // TStream will skip over objects that it can't understand.To do this, it writes the size
  78. // of each object in a known position.This means that writing an object is a 2 step
  79. // process. You first write the object header, by calling WriteObject, and after the entire
  80. // object is written you fill in its size, by calling WriteObjectSize.
  81. //
  82. // TStream::ReadObject will return NULL if it can't understand a particular object, or if
  83. // the object was actually NULL.  It returns a flag indicating the difference.
  84. //----------------------------------------------------------------------------------------
  85.  
  86. // passed to WriteStreamObject
  87. enum
  88. {
  89.     kNoStandardObject, kStandardObject
  90. };
  91.  
  92. //  written by WriteStreamObject, read by ReadStreamObject 
  93. enum
  94. {
  95.     kNullObject, kLocalObjectNumber, kClassIDAndClassname, kSignatureAndClassname
  96. };
  97.  
  98. // passed to TContext::Add()
  99. enum
  100. {
  101.     kDontForceReplacement, kForceReplacement
  102. };
  103.  
  104. //----------------------------------------------------------------------------------------
  105. // TContext: This is the context which holds references to objects "seen" by the stream.
  106. //----------------------------------------------------------------------------------------
  107. typedef long LocalObjectNumber;
  108.  
  109. class TContext : public TObject
  110. {
  111.     MA_DECLARE_CLASS;
  112.     
  113. public:
  114.     //------------------------------------------------------------------------------------
  115.     // Creation/Destruction
  116.     //------------------------------------------------------------------------------------
  117.  
  118.     TContext();
  119.         // Constructor
  120.         
  121.     void IContext();
  122.  
  123.     virtual ~TContext();
  124.         // Called to dispose of an object. Gives object a chance to clean up after itself.
  125.         // Default simply calls this->ShallowFree, which makes no attempt to free instance
  126.         // variables.  Should be overridden by any class which allocates space or owns
  127.         // other objects in its instance variables.  Be sure to call Inherited!
  128.  
  129.     //------------------------------------------------------------------------------------
  130.     // Miscellaneous protocol and support methods.
  131.     //------------------------------------------------------------------------------------
  132.  
  133.     virtual TObject* Clone();
  134.         // Makes a duplicate copy of this. The default calls this->ShallowClone, which
  135.         // makes a literal copy of instance variables but does not attempt to clone owned
  136.         // objects. A subclass which owns other objects should override this to clone the
  137.         // owned objects and data structures as well.
  138.  
  139.     //------------------------------------------------------------------------------------
  140.     // Context Methods
  141.     //------------------------------------------------------------------------------------
  142.  
  143.     virtual LocalObjectNumber Add(TObject* objectToAdd,
  144.                                          Boolean forceReplacement,
  145.                                          Boolean& newEntry);
  146.  
  147.     virtual TObject* Find(LocalObjectNumber name);
  148.  
  149.     //------------------------------------------------------------------------------------
  150.     // data members
  151.     //------------------------------------------------------------------------------------
  152. public:
  153.  
  154.     TList*    fOtherObjects;                        // the objects "seen" by this context
  155.  
  156. };
  157.  
  158.  
  159. typedef struct ClassIDEntry
  160. {
  161.     long fOldID;
  162.     long fNewID;
  163. } *PClassIDEntry, **HClassArray;
  164.  
  165.  
  166. //----------------------------------------------------------------------------------------
  167. // TStream: This is the abstract stream class. You would normally create instances of one
  168. // of the concrete subclasses below. 
  169. //----------------------------------------------------------------------------------------
  170.  
  171. class TStream : public TObject
  172. {
  173.     MA_DECLARE_CLASS;
  174.     
  175. public:
  176.     //------------------------------------------------------------------------------------
  177.     // Creation/Destruction
  178.     //------------------------------------------------------------------------------------
  179.  
  180.     TStream();
  181.         // Constructor
  182.         
  183.     void IStream();
  184.  
  185.     virtual ~TStream();
  186.  
  187.     //------------------------------------------------------------------------------------
  188.     // Access: These methods have default implementations that assume a 0-length stream. 
  189.     //------------------------------------------------------------------------------------
  190.  
  191.     virtual long GetPosition();
  192.  
  193.     virtual void SetPosition(long newPosition);
  194.  
  195.     virtual long GetSize();
  196.  
  197.     virtual void SetSize(long newSize);
  198.  
  199.  
  200.     //------------------------------------------------------------------------------------
  201.     // TContext mgmt.
  202.     //------------------------------------------------------------------------------------
  203.  
  204.     inline void SetContext(TContext* itsContext)
  205.     { fContext = itsContext; }
  206.  
  207.     inline TContext* GetContext()
  208.     { return fContext; }
  209.  
  210.     //------------------------------------------------------------------------------------
  211.     // Note - all reading and writing methods signal failure in case of an I/ O error.
  212.     //------------------------------------------------------------------------------------
  213.  
  214.     Boolean AtEnd();                
  215.         // Return true if at the end of the stream. 
  216.  
  217.     virtual void ReadBytes(void* p, long count); 
  218.         // This must be overridden by subclasses; all other reading methods call this. 
  219.  
  220.     Byte ReadByte();
  221.  
  222.     Boolean ReadBoolean();
  223.  
  224.     void ReadCharacter(short& data);
  225.  
  226.     short ReadInteger();
  227.  
  228.     long ReadLong();
  229.  
  230.     CPoint ReadPoint();
  231.  
  232.     void ReadVPoint(VPoint& data);
  233.  
  234.     void ReadRect(CRect& data);
  235.  
  236.     void ReadVRect(VRect& data);
  237.  
  238.     void ReadRGBColor(CRGBColor& data);
  239.  
  240.     IDType ReadIDType();
  241.  
  242.     void ReadString(CString& data, short maxSize); 
  243.         // Read a CString.maxSize is the amount of memory available, which is the maximum
  244.         // CString length + 1.If the size of the CString in the stream is too large, then
  245.         // it signals Failure with err=paramErr. 
  246.  
  247.     Handle ReadHandle(); 
  248.         // Read a handle from the stream and return it. 
  249.  
  250.     Boolean ReadObject(TObject*& data);
  251.         // Returns an uninitialized object; known is set to true if the object was valid
  252.         // (i.e., the class of the object is known to the program. The function result
  253.         // will be NULL if the object was unknown or if NULL was found in the stream. 
  254.  
  255.     Boolean ReadStdObject(TObject*& data);
  256.  
  257.     Boolean ReadStreamObject(TObject*& data);
  258.         // If stdObject is true, calls ReadStdObject, else calls ReadObject. If the
  259.         // result is not NULL, calls ReadFrom on the new object. 
  260.  
  261.     void ReadWordAlign();
  262.         // calls ReadBytes to bump ptr 1 byte to word align
  263.  
  264.  
  265.     //------------------------------------------------------------------------------------
  266.     // Writing
  267.     //------------------------------------------------------------------------------------
  268.  
  269.     virtual void WriteBytes(const void* p,
  270.                                    long count); 
  271.         // This must be overridden by subclasses; all other writing methods call this. 
  272.  
  273.     void WriteByte(Byte data);
  274.  
  275.     void WriteBoolean(Boolean data);
  276.  
  277.     void WriteCharacter(short data);
  278.  
  279.     void WriteInteger(short data);
  280.  
  281.     void WriteLong(long data);
  282.  
  283.     void WritePoint(CPoint data);
  284.  
  285.     void WriteVPoint(const VPoint& data);
  286.  
  287.     void WriteRect(const CRect& data);
  288.  
  289.     void WriteVRect(const VRect& data);
  290.  
  291.     void WriteRGBColor(const CRGBColor& data);
  292.     
  293.     void WriteIDType(const IDType data);
  294.  
  295.     void WriteString(const CString& data); 
  296.         // Write a CString. This takes a CStringPtr, so it can accommodate any size CString. 
  297.  
  298.     void WriteHandle(const Handle aHandle); 
  299.         // Locks the handle, dereferences it, and calls WriteBytes for the size of the
  300.         // handle.  Restores the handle to the state it was in.
  301.  
  302.     //------------------------------------------------------------------------------------
  303.     // These methods are used to write an object to a stream.You must call WriteObject
  304.     // first, then tell the object to write its specific data, and then call
  305.     // WriteObjectSize. 
  306.     //------------------------------------------------------------------------------------
  307.  
  308.     void WriteObject(TObject* data, long& sizePosition);
  309.  
  310.     void WriteStdObject(TObject* data,
  311.                                        long& sizePosition);
  312.  
  313.     void WriteObjectSize(long sizePosition);
  314.  
  315.     void WriteStreamObject(TObject* data,
  316.                                           Boolean stdObject = kNoStandardObject);
  317.         // This calls WriteObject, then data->WriteTo, and finally WriteObjectSize. 
  318.  
  319.     void WriteWordAlign();
  320.         // calls WriteBytes to bump ptr 1 byte to word align
  321.  
  322.  
  323.     //------------------------------------------------------------------------------------
  324.     // Class handling: used internally 
  325.     //------------------------------------------------------------------------------------
  326.  
  327.     long LookupClassID(long id);
  328.  
  329.     void RegisterClassID(long oldID, long newID);
  330.  
  331.     //------------------------------------------------------------------------------------
  332.     // data members
  333.     //------------------------------------------------------------------------------------
  334. public:
  335.  
  336.     TContext*    fContext;                        // remembers "seen" objects
  337.  
  338.     HClassArray fClassMap;                        // handle to class ID mapping table 
  339.  
  340.     short fClassMapSize;                        // number of entries in the table 
  341. };
  342.  
  343.  
  344. //----------------------------------------------------------------------------------------
  345. // THandleStream: This implements a stream into or out of a handle.The client is
  346. // responsible for allocating and disposing the handle. 
  347. //----------------------------------------------------------------------------------------
  348.  
  349. class THandleStream : public TStream
  350. {
  351.     MA_DECLARE_CLASS;
  352.     
  353. public:
  354.     //------------------------------------------------------------------------------------
  355.     // Creation/Destruction
  356.     //------------------------------------------------------------------------------------
  357.  
  358.     THandleStream();
  359.         // Constructor
  360.         
  361.     void IHandleStream(Handle itsHandle, long growth);
  362.         // Initialize stream; growth specifies how much to grow the handle when it needs
  363.         // to grow. You use this so that the handle isn't grown by a small number of bytes
  364.         // on each write operation. 
  365.                                       
  366.     virtual ~THandleStream();
  367.         // This also shrinks the handle to the current position, eliminating any extra
  368.         // space at the end. 
  369.  
  370.  
  371.     //------------------------------------------------------------------------------------
  372.     // Subclass implementations 
  373.     //------------------------------------------------------------------------------------
  374.  
  375.     virtual long GetPosition();
  376.  
  377.     virtual void SetPosition(long newPosition);
  378.  
  379.     virtual long GetSize();
  380.  
  381.     virtual void SetSize(long newSize);
  382.  
  383.     virtual void ReadBytes(void* p, long count); 
  384.  
  385.     virtual void WriteBytes(const void* p, long count); 
  386.  
  387.  
  388.     //------------------------------------------------------------------------------------
  389.     // Growing 
  390.     //------------------------------------------------------------------------------------
  391.  
  392.     virtual long GrowthSize(long needed);
  393.         // Returns amount to grow by, given that we need 'needed' bytes.Default is to grow
  394.         // by Max(fGrowth, needed). 
  395.  
  396.     //------------------------------------------------------------------------------------
  397.     // data members
  398.     //------------------------------------------------------------------------------------
  399. public:
  400.  
  401.     Handle fHandle;                                // the actual handle 
  402.  
  403.     long fPosition;                                // offset into the handle 
  404.  
  405.     long fSize;                                    // size of the stream (may be smaller than
  406.                                                 // handle) 
  407.  
  408.     long fGrowthSize;                            // how much to grow the handle when needed
  409.                                                 // 
  410.  
  411.     char fSavedState;                            // handle's saved state
  412.  
  413. };
  414.  
  415.  
  416. //----------------------------------------------------------------------------------------
  417. // TCountingStream: This implements a stream that counts up the total number of bytes. It
  418. // is only usable for writing. You will get a debugging break if you try to read from this
  419. // kind of stream. 
  420. //----------------------------------------------------------------------------------------
  421.  
  422. class TCountingStream : public TStream
  423. {
  424.     MA_DECLARE_CLASS;
  425.     
  426. public:
  427.     //------------------------------------------------------------------------------------
  428.     // Creation/Destruction 
  429.     //------------------------------------------------------------------------------------
  430.  
  431.     TCountingStream();
  432.         // Constructor
  433.     virtual ~TCountingStream();
  434.         // Destructor
  435.         
  436.     inline void ICountingStream()
  437.     { IStream(); }
  438.  
  439.  
  440.  
  441.     //------------------------------------------------------------------------------------
  442.     // Subclass implementations 
  443.     //------------------------------------------------------------------------------------
  444.  
  445.     virtual long GetPosition();                    // Override
  446.     virtual void SetPosition(long newPosition);    // Override
  447.     virtual long GetSize();                        // Override
  448.     virtual void SetSize(long newSize);            // Override
  449.  
  450.     virtual void WriteBytes(const void* p, long count);     // Override
  451.  
  452.     //------------------------------------------------------------------------------------
  453.     // data members
  454.     //------------------------------------------------------------------------------------
  455. public:
  456.  
  457.     long fPosition;                                // current position in the stream 
  458.  
  459.     long fSize;                                    // current size of stream 
  460.  
  461. };
  462.  
  463.  
  464. //----------------------------------------------------------------------------------------
  465. // TResourceStream: This implements a stream that reads and writes to partial resources.
  466. // Since the partial resources traps are only available in System 7, this stream class can
  467. // only be used under System 7. 
  468. //----------------------------------------------------------------------------------------
  469.  
  470. class TResourceStream : public TStream
  471. {
  472.     MA_DECLARE_CLASS;
  473.     
  474. public:
  475.     //------------------------------------------------------------------------------------
  476.     // Creation/Destruction 
  477.     //------------------------------------------------------------------------------------
  478.  
  479.     TResourceStream();
  480.         // Constructor
  481.     virtual ~TResourceStream();
  482.         // Destructor
  483.         
  484.     void IResourceStream(ResType theType, ResNumber theID);
  485.         // Initialize the TResourceStream.
  486.  
  487.     //------------------------------------------------------------------------------------
  488.     // Subclass implementations 
  489.     //------------------------------------------------------------------------------------
  490.  
  491.     virtual long GetPosition();
  492.         // Returns fPosition.
  493.  
  494.     virtual void SetPosition(long newPosition);
  495.         // Sets fPosition.
  496.     
  497.     virtual long GetSize();
  498.         // Returns fSize.
  499.  
  500.     virtual void SetSize(long newSize);
  501.         // Sets fSize.
  502.     
  503.     virtual void ReadBytes(void* p, long count);
  504.         // Reads bytes from the resource calling ReadPartialResource.
  505.  
  506.     virtual void WriteBytes(const void* p, long count);
  507.         // Write bytes to the resource calling WritePartialResource.
  508.  
  509.     //------------------------------------------------------------------------------------
  510.     // data members
  511.     //------------------------------------------------------------------------------------
  512. public:
  513.  
  514.     Handle fResource;                            // the resource to write to/ read from
  515.  
  516.     long fPosition;                                // offset into the resource
  517.  
  518.     long fSize;                                    // offset into the resource
  519. };
  520.  
  521.  
  522. #endif // __USTREAM__
  523.